/**
* File Name: rwlock.c
* Auther: Jichang
* Environment: Fedora 7 server
* use rwlock function
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>

int counter;
pthread_rwlock_t rwlock;

// three thread write one-globle resources in sometime
void *th_write(void *arg)
{
	int t;
	unsigned long i = (unsigned long)arg;
	while(1) {
		pthread_rwlock_wrlock(&rwlock);
		t = counter;
		usleep(1000);
		printf("==write %lu: %lu: counter=%d ++counter=%d\n", i, pthread_self(), t, ++counter);
		// unlock rightway.
		pthread_rwlock_unlock(&rwlock);
		usleep(1000);
	}
	return NULL;
}

// five thread read one-globle recources in sometime.
void *th_read(void *arg) 
{
	unsigned long i = (unsigned long)arg;
	while(1) {
		pthread_rwlock_rdlock(&rwlock);
		printf("--read %lu: %lu: %d\n", i, pthread_self(), counter);
		pthread_rwlock_unlock(&rwlock);
		usleep(2000);
	}
	return NULL;
}

int main(int argc, char *argv[])
{
	unsigned long i;
	int ret;
	pthread_t tid[8];
	// init
	ret = pthread_rwlock_init(&rwlock, NULL);
	if(ret != 0) {
		fprintf(stderr, "init error: %s\n", strerror(ret));
	}
	// write
	for(i = 0; i < 3; i++) {
		ret = pthread_create(&tid[i], NULL, th_write, (void *)i);
		if(ret != 0) {
			fprintf(stderr, "create error: %s\n", strerror(ret));
		}
	}
	// read
	for(i = 0; i < 5; i++) {
		ret = pthread_create(&tid[i+3], NULL, th_read, (void *)i);
		if(ret != 0) {
			fprintf(stderr, "create error: %s\n", strerror(ret));
		}
	}
	// reclaim
	for(i = 0; i < 8; i++) {
		ret = pthread_join(tid[i], NULL);
		if(ret != 0) {
			fprintf(stderr, "join error: %s\n", strerror(ret));
		}
	}
	// destroy
	pthread_rwlock_destroy(&rwlock);
	
	return 0;
}

